package zhishuang.wang.sansi.fcms.protocol;

/**
 * @Author Zhishuang.Wang
 * @Date 2023/7/5 10:52
 * @Email 1406110602@qq.com
 */


import zhishuang.wang.sansi.fcms.devinfor.DeviceInfor;
import zhishuang.wang.sansi.tcp.client.TcpSocketClient;
import zhishuang.wang.sansi.tools.ReturnData;
import zhishuang.wang.sansi.tools.time.DateFormat;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class FcmsDeviceControl {
    private TcpSocketClient TcpSocketClient = null;

    public FcmsDeviceControl(String ipAddr, int ipPort, int timeOut) {
        this.TcpSocketClient = new TcpSocketClient(ipAddr, ipPort, timeOut);
    }

    public FcmsDeviceControl(String ipAddr, int ipPort) {
        this.TcpSocketClient = new TcpSocketClient(ipAddr, ipPort, 5000);
    }

    public boolean closeSocketConenct() {
        if (this.TcpSocketClient != null) {
            this.TcpSocketClient.tcpSocketClose();
        }

        return true;
    }

    public ReturnData FcmsTimeReadDeal(DeviceInfor di) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        byte[] dataBuff = new byte[]{48, 55};
        byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, 2);
        if (proBuff != null) {
            return this.TcpSocketClient.sendDataToService(proBuff, di.getFcmsVersion(), 10);
        } else {
            rd.setMessage("校时协议封包错误");
            rd.setTime(DateFormat.getNowDataFormat());
            return rd;
        }
    }

    public ReturnData FcmsTimeSetDeal(DeviceInfor di) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        String fcmsTime = DateFormat.getNowDataFormatFcms();
        byte[] dataBuff = new byte[16];
        dataBuff[0] = 48;
        dataBuff[1] = 56;
        System.arraycopy(fcmsTime.getBytes(), 0, dataBuff, 2, 14);
        byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, 16);
        if (proBuff != null) {
            return this.TcpSocketClient.sendDataToService(proBuff, di.getFcmsVersion(), 9);
        } else {
            rd.setMessage("校时协议封包错误");
            rd.setTime(DateFormat.getNowDataFormat());
            return rd;
        }
    }

    public ReturnData fcmsParamSetDeal(DeviceInfor di, Map<String, String> paramMap) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        String paramType = (String)paramMap.get("paramType");
        int paramTypeInt = Integer.valueOf(paramType);
        byte[] dataBuff = new byte[10];
        int dataBuffLen = 0;
        dataBuff[0] = 52;
        dataBuff[1] = 57;
        dataBuff[2] = 0;
        dataBuff[3] = (byte)(paramTypeInt & 255);
        switch (paramTypeInt) {
            case 1:
                String paramVal = (String)paramMap.get("paramVal");
                int paramValInt = Integer.valueOf(paramVal);
                byte[] parambytes = ProtocolPackage.addIntToByte(paramValInt, 4);
                System.arraycopy(parambytes, 0, dataBuff, 4, 4);
                dataBuffLen = 8;
                break;
            case 2:
            case 3:
            case 4:
            default:
                rd.setMessage("仅支持设置block size参数");
        }

        if (dataBuffLen > 0) {
            byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, dataBuffLen);
            if (proBuff != null) {
                return this.TcpSocketClient.sendDataToService(proBuff, di.getFcmsVersion(), 8);
            }

            rd.setMessage("参数类型查询协议封包错误");
        }

        rd.setTime(DateFormat.getNowDataFormat());
        return rd;
    }

    public ReturnData fcmsParamReadDeal(DeviceInfor di, Map<String, String> paramMap) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        String paramType = (String)paramMap.get("paramType");
        int paramTypeInt = Integer.valueOf(paramType);
        if (paramTypeInt > 0 && paramTypeInt < 9) {
            String paramStr = String.format("%02d", paramTypeInt);
            byte[] dataBuff = new byte[]{52, 56, 0, (byte)(paramTypeInt & 255)};
            byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, 4);
            if (proBuff != null) {
                return this.TcpSocketClient.sendDataToService(proBuff, di.getFcmsVersion(), 7);
            }

            rd.setMessage("参数类型查询协议封包错误");
        } else {
            rd.setMessage("参数类型取值范围：1-8");
        }

        rd.setTime(DateFormat.getNowDataFormat());
        return rd;
    }

    private int readBlockSize(DeviceInfor di) {
        Map<String, String> map = new HashMap();
        map.put("paramType", "1");
        ReturnData rd = this.fcmsParamReadDeal(di, map);
        if (rd.getCode() == 0) {
            Map<String, Integer> res = (Map)rd.getData();
            Integer blockSize = (Integer)res.get("blockSize");
            return blockSize != null ? blockSize : -1;
        } else {
            return -1;
        }
    }

    public ReturnData fcmsFileUpload(DeviceInfor di, Map<String, String> paramMap) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        int offSize = 0;

        if (paramMap == null) {
            rd.setMessage("文件不存在，检查文件路径或文件是否正确， 路径格式：linux环境 /xxxx/xxxx/ 或 win环境 D:\\xxx\\");
            rd.setTime(DateFormat.getNowDataFormat());
            return rd;
        } else {
            int blockSize = di.getBlockSize();
            String filePath = (String)paramMap.get("localFileName");
            String fileName = (String)paramMap.get("devFileName");
            if (filePath != null && fileName != null) {
                FileInputStream fs = null;

                try {
                    int downNum = 0;
                    File readfile = new File(filePath);
                    if (readfile.exists()) {
                        fs = new FileInputStream(readfile);
                        int fileNameLen = fileName.length();
                        byte[] dataBuff = new byte[blockSize + 100];
                        byte[] contentBuff = new byte[blockSize];

                        dataBuff[0] = 49;
                        dataBuff[1] = 48;
                        System.arraycopy(fileName.getBytes(), 0, dataBuff, 2, fileNameLen);
                        int dataBuffLen = fileNameLen + 7;
                        dataBuff[dataBuffLen - 5] = 43;

                        while(true) {
                            dataBuff[dataBuffLen - 4] = (byte)(offSize >> 24 & 255);
                            dataBuff[dataBuffLen - 3] = (byte)(offSize >> 16 & 255);
                            dataBuff[dataBuffLen - 2] = (byte)(offSize >> 8 & 255);
                            dataBuff[dataBuffLen - 1] = (byte)(offSize & 255);
                            int fileDatabyteLen = fs.read(contentBuff);
                            System.arraycopy(contentBuff, 0, dataBuff, dataBuffLen, fileDatabyteLen);
                            fileDatabyteLen += dataBuffLen;
                            byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, fileDatabyteLen);
                            if (proBuff == null) {
                                rd.setMessage("文件上传协议封包错误");
                                break;
                            }

                            byte[] resDataByte = this.TcpSocketClient.fileDataPassThrough(proBuff, blockSize);
                            if (resDataByte == null) {
                                rd.setMessage("文件发送失败，请重试");
                                break;
                            }

                            if (resDataByte[3] != 48) {
                                fileDatabyteLen = resDataByte.length - 7;
                                byte[] errMessage = Arrays.copyOfRange(resDataByte, 4, fileDatabyteLen);
                                rd.setMessage(new String(errMessage));
                                break;
                            }

                            rd.setCode(0);
                            rd.setMessage("上传文件成功");
                            if (fileDatabyteLen < blockSize) {
                                break;
                            }

                            ++downNum;
                            offSize = downNum * blockSize;
                        }
                    } else {
                        rd.setMessage("文件不存在，检查文件路径或文件是否正确， 路径格式：/xxxx/xxxx/ 或 D:\\xxx\\");
                    }
                } catch (FileNotFoundException var20) {
                    var20.printStackTrace();
                } catch (IOException var21) {
                    var21.printStackTrace();
                }

                try {
                    if (fs != null) {
                        fs.close();
                    }
                } catch (IOException var19) {
                    var19.printStackTrace();
                }
            } else {
                rd.setMessage("本地文件路径或设备存储路径必填");
            }

            rd.setTime(DateFormat.getNowDataFormat());
            return rd;
        }
    }

    public ReturnData fcmsFileDown(DeviceInfor di, Map<String, String> paramMap) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        int offSize = 0;

        if (paramMap == null) {
            rd.setMessage("文件存储路径和下载文件必填");
            rd.setTime(DateFormat.getNowDataFormat());
            return rd;
        } else {
            int blockSize = di.getBlockSize();
            String filePath = (String)paramMap.get("localFileName");
            String fileName = (String)paramMap.get("devFileName");
            if (filePath != null && fileName != null) {
                int downNum = 0;
                FileOutputStream fs = null;
                File writefile = new File(filePath);
                File fileParent = writefile.getParentFile();

                try {
                    if (fileParent != null && !fileParent.exists()) {
                        fileParent.mkdirs();
                    }

                    if (writefile.exists()) {
                        writefile.delete();
                    }

                    writefile.createNewFile();
                    fs = new FileOutputStream(writefile);
                    int fileNameLen = fileName.length();
                    int dataByteLen = fileNameLen + 6;
                    byte[] dataBuff = new byte[dataByteLen];
                    dataBuff[0] = 48;
                    dataBuff[1] = 57;
                    System.arraycopy(fileName.getBytes(), 0, dataBuff, 2, fileNameLen);

                    while(true) {
                        dataBuff[dataByteLen - 4] = (byte)(offSize >> 24 & 255);
                        dataBuff[dataByteLen - 3] = (byte)(offSize >> 16 & 255);
                        dataBuff[dataByteLen - 2] = (byte)(offSize >> 8 & 255);
                        dataBuff[dataByteLen - 1] = (byte)(offSize & 255);
                        byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, dataByteLen);
                        if (proBuff == null) {
                            rd.setMessage("文件下载协议封包错误");
                            break;
                        }

                        byte[] resDataByte = this.TcpSocketClient.fileDataPassThrough(proBuff, blockSize);
                        if (resDataByte == null) {
                            rd.setMessage("文件不存在或网络超时");
                            break;
                        }

                        int fileDatabyteLen = resDataByte.length - 6;
                        if (fileDatabyteLen <= 0) {
                            rd.setCode(0);
                            rd.setMessage("文件下载成功");
                            break;
                        }

                        byte[] fileDatabyte = Arrays.copyOfRange(resDataByte, 3, 3 + fileDatabyteLen);
                        fs.write(fileDatabyte);
                        if (fileDatabyteLen < blockSize) {
                            rd.setCode(0);
                            rd.setMessage("文件下载成功");
                            break;
                        }

                        ++downNum;
                        offSize = blockSize * downNum;
                    }
                } catch (FileNotFoundException var20) {
                    var20.printStackTrace();
                } catch (IOException var21) {
                    var21.printStackTrace();
                } catch (Exception var22) {
                    var22.printStackTrace();
                }

                try {
                    if (fs != null) {
                        fs.flush();
                    }

                    if (fs != null) {
                        fs.close();
                    }
                } catch (IOException var19) {
                    var19.printStackTrace();
                }

                if (rd.getCode() != 0 && writefile.exists()) {
                    writefile.delete();
                }
            } else {
                rd.setMessage("文件存储路径和下载文件必填");
            }

            rd.setTime(DateFormat.getNowDataFormat());
            return rd;
        }
    }

    private ReturnData fcmsSetLightMode(DeviceInfor di, int lightMode) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        if (lightMode != 0 && lightMode != 1) {
            rd.setMessage("亮度模式取值范围 ： 0 或 1");
        } else {
            byte[] dataBuff = new byte[]{48, 52, 0};
            lightMode += 48;
            dataBuff[2] = (byte)(lightMode & 255);
            byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, 3);
            if (proBuff != null) {
                return this.TcpSocketClient.sendDataToService(proBuff, di.getFcmsVersion(), 4);
            }

            rd.setMessage("设置亮度模式询协议封包错误");
        }

        rd.setTime(DateFormat.getNowDataFormat());
        return rd;
    }

    private ReturnData fcmsSetLightVal(DeviceInfor di, int lightVal) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        if (lightVal > -1 && lightVal < 32) {
            byte[] dataBuff = new byte[8];
            dataBuff[0] = 48;
            dataBuff[1] = 53;
            int hVal = 48 + lightVal / 10;
            int lVal = 48 + lightVal % 10;
            dataBuff[2] = (byte)hVal;
            dataBuff[3] = (byte)lVal;
            dataBuff[4] = (byte)hVal;
            dataBuff[5] = (byte)lVal;
            dataBuff[6] = (byte)hVal;
            dataBuff[7] = (byte)lVal;
            byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, 8);
            if (proBuff != null) {
                return this.TcpSocketClient.sendDataToService(proBuff, di.getFcmsVersion(), 5);
            }

            rd.setMessage("设置亮度模式询协议封包错误");
        } else {
            rd.setMessage("亮度值取值范围 ： 0-31");
        }

        rd.setTime(DateFormat.getNowDataFormat());
        return rd;
    }

    public ReturnData fcmsSetLightAndMode(DeviceInfor di, Map<String, String> paramMap) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        if (paramMap != null) {
            String lightMode = (String)paramMap.get("lightMode");
            String lightVal = (String)paramMap.get("lightVal");
            if (lightMode != null && lightVal != null) {
                int lightModeInt = Integer.valueOf(lightMode);
                int lightValInt = Integer.valueOf(lightVal);
                if (lightModeInt >= 0 && lightModeInt <= 1) {
                    if (lightValInt >= 0 && lightValInt <= 100) {
                        ReturnData modeRd = this.fcmsSetLightMode(di, lightModeInt);
                        if (modeRd.getCode() != 0) {
                            return modeRd;
                        }

                        lightValInt = ProtocolPackage.dimPerToGrade(lightValInt);
                        modeRd = this.fcmsSetLightVal(di, lightValInt);
                        if (modeRd.getCode() != 0) {
                            return modeRd;
                        }

                        lightModeInt = ProtocolPackage.dimGradeToPer(lightValInt);
                        Map<String, Integer> map = (Map)modeRd.getData();
                        map.put("lightVal", lightModeInt);
                        modeRd.setData(map);
                        return modeRd;
                    }

                    rd.setMessage("亮度值取值范围：0 - 100");
                } else {
                    rd.setMessage("调节模式取值范围：0或1");
                }
            } else {
                rd.setMessage("亮度调节模式和亮度值必填");
            }
        } else {
            rd.setMessage("亮度调节模式和亮度值必填");
        }

        rd.setTime(DateFormat.getNowDataFormat());
        return rd;
    }

    public ReturnData fcmsReadLighValAndMode(DeviceInfor di) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        byte[] dataBuff = new byte[]{48, 54};
        byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, 2);
        if (proBuff != null) {
            return this.TcpSocketClient.sendDataToService(proBuff, di.getFcmsVersion(), 6);
        } else {
            rd.setMessage("亮度和调节模式协议封包错误");
            rd.setTime(DateFormat.getNowDataFormat());
            return rd;
        }
    }

    public ReturnData fcmsSetPreset(DeviceInfor di, Map<String, String> paramMap) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        if (paramMap != null) {
            String presetCode = (String)paramMap.get("playListName");
            if (presetCode != null && presetCode.length() == 3) {
                byte[] dataBuff = new byte[]{57, 56, 0, 0, 0};
                byte[] presetByte = presetCode.getBytes();
                System.arraycopy(presetByte, 0, dataBuff, 2, 3);
                byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, 5);
                if (proBuff != null) {
                    return this.TcpSocketClient.sendDataToService(proBuff, di.getFcmsVersion(), 3);
                }

                rd.setMessage("激活播放表协议封包错误");
            } else {
                rd.setMessage("预置播放表名称 playListName 必填且长度必须是 3,playListName不可包含路径信息只能是播放表名称信息");
            }
        } else {
            rd.setMessage("预置播放表名称 playListName 必填且长度必须是3");
        }

        rd.setTime(DateFormat.getNowDataFormat());
        return rd;
    }

    public ReturnData fcmsFaultQuery(DeviceInfor di) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        byte[] dataBuff = new byte[]{48, 49};
        byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, 2);
        if (proBuff != null) {
            return this.TcpSocketClient.sendDataToService(proBuff, di.getFcmsVersion(), 1);
        } else {
            rd.setMessage("故障查询协议封包错误");
            rd.setTime(DateFormat.getNowDataFormat());
            return rd;
        }
    }

    public ReturnData fcmsShowInforQuery(DeviceInfor di) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        byte[] dataBuff = new byte[]{57, 55};
        byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, 2);
        if (proBuff != null) {
            return this.TcpSocketClient.sendDataToService(proBuff, di.getFcmsVersion(), 2);
        } else {
            rd.setMessage("当前显示内容协议封包错误");
            rd.setTime(DateFormat.getNowDataFormat());
            return rd;
        }
    }

    public ReturnData fcmsReboot(DeviceInfor di) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        byte[] dataBuff = new byte[]{49, 49};
        byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, 2);
        if (proBuff != null) {
            return this.TcpSocketClient.sendDataToService(proBuff, di.getFcmsVersion(), 19);
        } else {
            rd.setMessage("当前重启协议协议封包错误");
            rd.setTime(DateFormat.getNowDataFormat());
            return rd;
        }
    }

    public ReturnData fcmsFileListQuery(DeviceInfor di, String fileName) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        int size = fileName.length();
        byte[] dataBuff = new byte[2 + size];
        dataBuff[0] = 49;
        dataBuff[1] = 52;
        System.arraycopy(fileName.getBytes(), 0, dataBuff, 2, size);
        size += 2;
        byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, size);
        if (proBuff != null) {
            return this.TcpSocketClient.sendDataToService(proBuff, di.getFcmsVersion(), 18);
        } else {
            rd.setMessage("当前重启协议协议封包错误");
            rd.setTime(DateFormat.getNowDataFormat());
            return rd;
        }
    }

    public ReturnData fcmsDeleteFile(DeviceInfor di, Map<String, String> paramMap) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        String devFileName = (String)paramMap.get("devFileName");
        int size = devFileName.length();
        byte[] dataBuff = new byte[2 + size];
        dataBuff[0] = 49;
        dataBuff[1] = 57;
        System.arraycopy(devFileName.getBytes(), 0, dataBuff, 2, size);
        size += 2;
        byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, size);
        if (proBuff != null) {
            return this.TcpSocketClient.sendDataToService(proBuff, di.getFcmsVersion(), 17);
        } else {
            rd.setMessage("重启协议封包错误");
            rd.setTime(DateFormat.getNowDataFormat());
            return rd;
        }
    }

    public ReturnData fcmsDeviceSwitch(DeviceInfor di, Map<String, String> paramMap) {
        ReturnData rd = new ReturnData();
        rd.setCode(1);
        String switchVal = (String)paramMap.get("switchVal");
        int switchValInt = Integer.valueOf(switchVal);
        if (switchValInt >= 0 && switchValInt <= 1) {
            byte[] dataBuff = new byte[]{50, 52, 0};
            switchValInt += 48;
            dataBuff[2] = (byte)(switchValInt & 255);
            byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, 3);
            if (proBuff != null) {
                return this.TcpSocketClient.sendDataToService(proBuff, di.getFcmsVersion(), 20);
            }

            rd.setMessage("开关屏协议封包错误");
        } else {
            rd.setMessage("开关屏参数取值范围：0 或 1");
        }

        rd.setTime(DateFormat.getNowDataFormat());
        return rd;
    }

    public ReturnData fcmsLedSelfTest(DeviceInfor di) {
        ReturnData rd = new ReturnData();
        byte[] dataBuff = new byte[]{48, 48};
        byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, 2);
        if (proBuff != null) {
            return this.TcpSocketClient.sendDataToService(proBuff, di.getFcmsVersion(), 21);
        } else {
            rd.setMessage("自检协议封包错误");
            rd.setTime(DateFormat.getNowDataFormat());
            return rd;
        }
    }

    public ReturnData fcmsDevVersionRead(DeviceInfor di) {
        ReturnData rd = new ReturnData();
        byte[] dataBuff = new byte[]{57, 57};
        byte[] proBuff = ProtocolPackage.fcmsPackageToSend(dataBuff, 2);
        if (proBuff != null) {
            return this.TcpSocketClient.sendDataToService(proBuff, di.getFcmsVersion(), 23);
        } else {
            rd.setMessage("读取版本号协议封包错误");
            rd.setTime(DateFormat.getNowDataFormat());
            return rd;
        }
    }
}
